package com.excel.demo.excel.controller;


import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.bean.BeanUtil;
import com.excel.demo.excel.common.api.CommonResult;
import com.excel.demo.excel.model.ReadExcel;
import com.excel.demo.excel.model.ReadExcelDto;
import com.excel.demo.excel.service.ReadExcelService;
import com.excel.demo.excel.util.ExcelUtil;
import com.excel.demo.excel.util.MyExcelExportStyler;
import com.excel.demo.excel.util.ThreadReadExcel;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Future;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ljj
 * @since 2022-04-09
 */
@RestController
@RequestMapping("/readExcel")
public class ReadExcelController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ReadExcelController.class);
    @Autowired
    private ReadExcelService readExcelService;
    @Autowired
    private ThreadReadExcel threadReadExcel;

    @RequestMapping(value = "/importZclist", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult importZclist(@RequestPart("file") MultipartFile[] file) {
        try {
            //取第一個文件名
            String fileName = file[0].getResource().getFilename();
            //excel合并后名字根据第一个文件而定，去后缀
            if (!StringUtils.isEmpty(fileName)) {
                String[] split = fileName.split("\\.");
                fileName = split.length > 0 ? split[0] : fileName;
            }
            //先清空数据库
            readExcelService.deleteAll();

            List<ReadExcel> allList = new ArrayList<>();

            //这里利用CountDownLatch，使子线程线程执行完再到主线程执行（还可以用循环isDone()方法和CyclicBarrier）
            CountDownLatch latch = new CountDownLatch(file.length);
            //保存多个future，用于后面获取返回值
            List<Future> futures = new ArrayList<>();
            for (int i = 0; i < file.length; i++) {
                LOGGER.info("======i:"+i+"=======");
                MultipartFile mf = file[i];
                //多线程执行任务，传递latch
                Future<List<ReadExcel>> future = threadReadExcel.importExcel(mf,latch);
                futures.add(future);
            }
            //注意：只能在for外面才能获取Future.get()，否则子线程只能逐个执行
            for (Future f: futures){
                allList.addAll((List)f.get());
            }
            LOGGER.info("_________before await");
            latch.await();
            LOGGER.info("_________after await");
            //添加空行保存文件名
            ReadExcel readExcel = new ReadExcel();
            readExcel.setFilename(fileName);
            Integer countName = readExcelService.saveReadExcel(readExcel);
            LOGGER.info("save_filename:" + fileName + " count:" + countName);
            return CommonResult.success(allList);
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.failed("导入失败！");
        }
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        List<Map<String, Object>> sheetsList = new ArrayList<>();
        List<String> cfaddressList = readExcelService.selectAllCfaddress();
        for(String addr: cfaddressList){
            int i =1;
            List<ReadExcel> readExcelList = readExcelService.selectReadExcelByAddr(addr);
            List<ReadExcelDto> readExcelNewList = new ArrayList<>();
            for (ReadExcel readExcel:readExcelList){
                ReadExcelDto readExcelDto = new ReadExcelDto();
                BeanUtil.copyProperties(readExcel,readExcelDto);
                readExcelDto.setXh(String.valueOf(i));
                readExcelNewList.add(readExcelDto);
                i++;
            }
            ExportParams reportWorkExportParams = new ExportParams();
            reportWorkExportParams.setSheetName(addr);
            reportWorkExportParams.setTitle("固定资产明细表（"+addr+"）");
            reportWorkExportParams.setTitleHeight((short)10);
            reportWorkExportParams.setSecondTitleHeight((short)5);
            reportWorkExportParams.setStyle(MyExcelExportStyler.class); // 设置样式
            // 创建sheet使用得map
            Map<String, Object> reportWorkExportMap = new HashMap<>();
            // title的参数为ExportParams类型，目前仅仅在ExportParams中设置了sheetName
            reportWorkExportMap.put("title", reportWorkExportParams);
            // 模版导出对应得实体类型
            reportWorkExportMap.put("entity", ReadExcelDto.class);
            // sheet中要填充得数据
            reportWorkExportMap.put("data", readExcelNewList);
            sheetsList.add(reportWorkExportMap);
        }


        String fileName = readExcelService.selectFileName();
        if (!StringUtils.isEmpty(fileName)) {
            fileName = fileName.substring(0, fileName.indexOf("表") == -1 ? fileName.length() : fileName.indexOf("表")) + "(存放地址)";
        } else {
            fileName = "华南20XX年度固定资产明细表(存放地址)";
        }
        ExcelUtil.exportExcel(sheetsList, ExcelType.XSSF, fileName, cfaddressList.size(), response);

    }
}

